using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Transactions;
using System.Web;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Xsl;
using DotNetNuke.Entities.Users;
using DotNetNuke.Services.Localization;
using DotNetNuke.UI.UserControls;

namespace Code5Systems.FormMaster.Business
{

	public partial class FormDataController
	{
		//Implements Entities.Modules.IPortable
		
#region Form Related Methods
		public XDocument GetFormResults(int moduleId, Panel pnlForm, string modulePath, List<string> disabledValidators, int portalId = -1, int userId = 0, int formDataId = 0)
		{
			bool bDidRoleBack = false;
			XDocument xResultsDoc = null;
			FormSettings objFormSettings = Utility.GetFormSettings(moduleId);
			
			if (objFormSettings.UseTransactions)
			{
				using (TransactionScope scope = new TransactionScope())
				{
					try
					{
						xResultsDoc = GetFormPostResults(moduleId, pnlForm, modulePath, disabledValidators, portalId, userId, formDataId);
						scope.Complete();
					}
					catch (IOException)
					{
						bDidRoleBack = true;
						throw;
					}
					catch (SqlException)
					{
						bDidRoleBack = true;
						throw;
					}
					catch (Exception)
					{
						bDidRoleBack = true;
						throw;
					}
					finally
					{
						if (bDidRoleBack)
						{
							foreach (string item in _alSavedFiles)
							{
								if (File.Exists(item))
								{
									File.Delete(item);
								}
							}
						}
					}
				}
				
			}
			else
			{
				xResultsDoc = GetFormPostResults(moduleId, pnlForm, modulePath, disabledValidators, portalId, userId, formDataId);
			}
			
			return xResultsDoc;
			
		}
		
		//Gets the results of the Form Post into a Class Scope XmlDocument Object
		//Populates a Class Scope XmlDocument Object with the posted values.
		private XDocument GetFormPostResults(int moduleId, Panel pnlForm, string modulePath, List<string> disabledValidators, int portalId = -1, int userId = 0, int formDataId = 0)
		{
			bool isUpdate = false;
			FormDataInfo oFormDataInfo = null;
			XDocument xDoc = default(XDocument);
			XDocument xResultsDoc = default(XDocument);
			FormController objFormCtl = default(FormController);
			WebControl oWebControl = null;
			HtmlControl oHtmlControl = null;
			HtmlInputHidden oHiddenField = null;
			TextEditor oTextEditor = null;
			FormControlInfo oFormControlInfo = default(FormControlInfo);
			List<FormControlInfo> controlsArray = default(List<FormControlInfo>);
			XElement xFormPagesElement = default(XElement);
			XElement xFormPageElement = default(XElement);
			string strEmailSendToControl = "";
			XElement oFieldElement = null;
			XElement oQuestonElement = default(XElement);
			XElement oAnswersElement = default(XElement);
			string strAnswer = "";
			XElement xNode = default(XElement);
			string strQuestion = default(string);
			string strQParams = "";
			string strPostParams = "";
			WebControl formContainer;
			
			FormSettings objFormSettings = Utility.GetFormSettings(moduleId);
			
			objFormCtl = new FormController(moduleId);
			
			//Load up the Xml Document Results Template from disk
			xResultsDoc = XDocument.Load(HttpContext.Current.Server.MapPath(modulePath + "/assets/xml/FormResults.xml"));
			
			if (!objFormSettings.HidePostedBy)
			{
				//Add the Submitted By User Information
				GetSubmittedBy(xResultsDoc, portalId, userId);
			}
			
			if (objFormCtl.Pages.Count == 1)
			{
				formContainer = pnlForm;
			}
			else
			{
				formContainer = (WebControl) (pnlForm.FindControl("formWizard"));
			}
			
			// Get the Pages Element
			xFormPagesElement = xResultsDoc.Root.Elements("Pages").SingleOrDefault();
			
			xResultsDoc.Root.Add(new XAttribute("Date", DateTime.Now.ToString("g")));
			
			xNode = xResultsDoc.Root.Elements("FormName").SingleOrDefault();
			if (xNode != null)
			{
				xNode.Value = objFormCtl.FormInfo.FormName;
			}
			
			//If we have Upload files to store in the DB we need a FormDataID to create the Relationship
			//so save the form data then update when complete
			if (objFormCtl.FormInfo.SaveData)
			{
				//Is this an Update
				
				if (formDataId > 0)
				{
					oFormDataInfo = this.Get(formDataId, moduleId);
				}
				
				if (oFormDataInfo == null)
				{
					oFormDataInfo = new FormDataInfo();
					oFormDataInfo.FormID = objFormCtl.FormInfo.FormID;
					oFormDataInfo.PortalID = portalId;
					oFormDataInfo.ModuleID = moduleId;
					oFormDataInfo.FormData = string.Empty;
					oFormDataInfo.CreatedByID = userId;
					
					//Add the FormData to the Form Master Data Table
					//Any External Table storage will hapen later
					oFormDataInfo.FormDataID = Add(oFormDataInfo);
					formDataId = oFormDataInfo.FormDataID;
				}
				else
				{
					isUpdate = true;
				}
			}
			
			foreach (FormPageInfo curPage in objFormCtl.Pages)
			{
				
				xDoc = XDocument.Parse(curPage.PageData);
				
				//Sort the controls so they conform to the layout of the form
				xDoc = SortControls(xDoc, modulePath);
				
				xFormPageElement = new XElement("Page");
				xFormPageElement.Add(new XAttribute("PageNum", curPage.PageNum));
				xFormPageElement.Add(new XAttribute("ExtTableName", curPage.ExtTableName));
				xFormPageElement.Add(new XAttribute("ExtIdentityColumn", curPage.ExtIdentityColumn));
				xFormPageElement.Add(new XAttribute("ExtTableConnStr", curPage.ExtTableConnStr));
				xFormPagesElement.Add(xFormPageElement);
				
				if (xFormPageElement != null)
				{
					
					if (xResultsDoc.Root.Attributes("FormDataID").FirstOrDefault() == null)
					{
						xResultsDoc.Root.Add(new XAttribute("FormDataID", formDataId));
					}
					
					controlsArray = objFormCtl.GetFormControlArray(xDoc);
					
					//Determine if we are using a Form Value for the Send To Email address
					if (((int)objFormCtl.FormInfo.EmailSendAction).ToEnum<FormInfo.EmailActionNone>() == FormInfo.EmailActionNone.UseForm)
					{
						strEmailSendToControl = objFormCtl.FormInfo.EmailSendToControl;
					}
					
					FormFileDataController oFileDataCtl = new FormFileDataController();
					List<FormFileDataInfo> aryFileDataInfo = null;
					if (formDataId > 0)
					{
						aryFileDataInfo = oFileDataCtl.GetByFormData(formDataId);
					}
					
					//Iterate the FormControlInfo Objects and retrieve the Posted values to build the Xml Document
					System.Collections.IEnumerator myEnumerator = controlsArray.GetEnumerator();
					while (myEnumerator.MoveNext())
					{
						//bIsCompareField = false;
						
						oFormControlInfo = (FormControlInfo) myEnumerator.Current;
						
						if (oFormControlInfo.Type != ControlType.Label && oFormControlInfo.Type != ControlType.SubmitButton)
						{
							
							strQuestion = Utility.GetValidControlID(oFormControlInfo.FieldName);
							if (string.IsNullOrEmpty(strQuestion))
							{
								strQuestion = Utility.GetValidControlID(oFormControlInfo.Label);
							}
							
							oFieldElement = new XElement("Field");
							xFormPageElement.Add(oFieldElement);
							
							oFieldElement.Add(new XAttribute("ID", oFormControlInfo.ID));
							
							foreach (FormControlInfo validator in oFormControlInfo.Validators)
							{
								string disVal = (string) ((from d in disabledValidators where d.EndsWith(validator.ID) select d).SingleOrDefault());
								if (!string.IsNullOrEmpty(disVal))
								{
									if (oFieldElement.Attributes("DisabledByFieldRule").FirstOrDefault() != null)
									{
										if (oFieldElement.Attributes("DisabledByFieldRule").First().Value == null)
										{
											oFieldElement.Add(new XAttribute("DisabledByFieldRule", "true"));
										}
									}
								}
							}
							
							oQuestonElement = new XElement("Question", strQuestion);
							oFieldElement.Add(oQuestonElement);
							
							oAnswersElement = new XElement("Answers");
							oFieldElement.Add(oAnswersElement);
							
							switch (oFormControlInfo.Type)
							{
								case ControlType.FileUpload:
									oHtmlControl = Utility.GetChildsRecursive(pnlForm).OfType<HtmlControl>().Where(c => c.ID == oFormControlInfo.ID).FirstOrDefault();
									break;
								case ControlType.HiddenField:
									oHiddenField = Utility.GetChildsRecursive(pnlForm).OfType<HtmlInputHidden>().Where(c => c.ID == oFormControlInfo.ID).FirstOrDefault();
									if (oHiddenField == null)
									{
										oHiddenField = Utility.GetChildsRecursive(pnlForm).OfType<HtmlInputHidden>().Where(c => c.ID == "datarecordid").FirstOrDefault();
									}
									break;
								case ControlType.HTMLEditor:
									oTextEditor = Utility.GetChildsRecursive(pnlForm).OfType<TextEditor>().Where(c => c.ID == oFormControlInfo.ID).FirstOrDefault();
									break;
								default:
									oWebControl = Utility.GetChildsRecursive(pnlForm).OfType<WebControl>().Where(c => c.ID == oFormControlInfo.ID).FirstOrDefault();
									break;
							}
							
							
							if ((oWebControl != null) || (oHtmlControl != null) || (oHiddenField != null) || (oTextEditor != null))
							{
								
								strAnswer = string.Empty;
								
								switch (oFormControlInfo.Type)
								{
									case ControlType.CheckBox:
										C5CheckBox chkBox = oWebControl as C5CheckBox;
										if (chkBox.Value == "C5SLLC")
											chkBox.Value = String.Empty;
										strAnswer = String.Format("{0}:{1}", Localization.GetString("No", Utility.GetSharedResourceFile()), chkBox.Value);
										if (chkBox.Checked)
										{
											strAnswer = String.Format("{0}:{1}", Localization.GetString("Yes", Utility.GetSharedResourceFile()), chkBox.Value);
										}
										
										AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
										break;
										
									case ControlType.TextBox:
										if (oFormControlInfo.UseCalendar)
										{
											Telerik.Web.UI.RadDatePicker picker = (Telerik.Web.UI.RadDatePicker)oWebControl;
											if (picker.SelectedDate.HasValue)
											{
												strAnswer = Utility.CleanInput(picker.SelectedDate.Value.ToShortDateString(), oFormControlInfo.AllowMarkup);
											}
										}
										else if (((TextBox) oWebControl).Text != string.Empty)
										{
											strAnswer = Utility.CleanInput((string) (((TextBox) oWebControl).Text), oFormControlInfo.AllowMarkup);
										}
										
										AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
										break;
										
									case ControlType.RadioButtonList:
										C5RadioButtonList rbLis = oWebControl as C5RadioButtonList;
										if (rbLis.SelectedIndex > -1)
										{
											if (oFormControlInfo.ListItemToSave == FormController.ListItemToSave.Text)
											{
												strAnswer = Utility.CleanInput((string)(rbLis.SelectedItem.Text), oFormControlInfo.AllowMarkup);
											}
											else
											{
												strAnswer = Utility.CleanInput((string)(rbLis.SelectedItem.Value), oFormControlInfo.AllowMarkup);
											}
											
										}
										
										AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
										break;
										
									case ControlType.DropDownList:
										if (((DropDownList) oWebControl).SelectedIndex > -1)
										{
											if (oFormControlInfo.ListItemToSave == FormController.ListItemToSave.Text)
											{
												strAnswer = Utility.CleanInput(((DropDownList) oWebControl).SelectedItem.Text, oFormControlInfo.AllowMarkup);
											}
											else
											{
												strAnswer = Utility.CleanInput(((DropDownList) oWebControl).SelectedItem.Value, oFormControlInfo.AllowMarkup);
											}
										}
										
										AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
										break;
										
									case ControlType.CheckBoxList:
										string[] ansGroup = null;
										string paramName = default(string);
										C5CheckBoxList oCheckBoxList = oWebControl as C5CheckBoxList;
										ListItem oListItem_1 = default(ListItem);
										XElement ansElement = default(XElement);
										Regex myRegEx = new Regex("\\[#\\]");
										foreach (ListItem tempLoopVar_oListItem_1 in oCheckBoxList.Items)
										{
											oListItem_1 = tempLoopVar_oListItem_1;
											paramName = string.Empty;
											if (oListItem_1.Selected)
											{
												if (oFormControlInfo.ListItemToSave == FormController.ListItemToSave.Text)
												{
													strAnswer = Utility.CleanInput(oListItem_1.Text, oFormControlInfo.AllowMarkup);
												}
												else
												{
													ansGroup = myRegEx.Split(oListItem_1.Value, 2);
													if (ansGroup.Length > 0)
													{
														strAnswer = ansGroup[0];
														strAnswer = Utility.CleanInput(strAnswer, oFormControlInfo.AllowMarkup);
													}
													
													if (ansGroup.Length == 2 && !string.IsNullOrEmpty(ansGroup[1]))
													{
														paramName = ansGroup[1];
													}
												}
												
												ansElement = AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
												if (!string.IsNullOrEmpty(paramName))
												{
													Utility.AddAttribute(xDoc, ansElement, "ParamName", paramName);
												}
											}
										}
										break;
										
									case ControlType.ListBox:
										ListBox oListBox = (ListBox) oWebControl;
										ListItem oListItem = default(ListItem);
										foreach (ListItem tempLoopVar_oListItem in oListBox.Items)
										{
											oListItem = tempLoopVar_oListItem;
											if (oListItem.Selected)
											{
												if (oFormControlInfo.ListItemToSave == FormController.ListItemToSave.Text)
												{
													strAnswer = Utility.CleanInput(oListItem.Text, oFormControlInfo.AllowMarkup);
												}
												else
												{
													strAnswer = Utility.CleanInput(oListItem.Value, oFormControlInfo.AllowMarkup);
												}
												
												AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
												
											}
										}
										break;
										
									case ControlType.HiddenField:
										if (oFormControlInfo.FieldName.ToLower() == "datarecordid")
										{
											strAnswer = formDataId.ToString();
										}
										else if (oFormControlInfo.FieldName.ToLower() == "clientid")
										{
											strAnswer = HttpContext.Current.Request.UserHostAddress;
										}
										else if (oFormControlInfo.FieldName.ToLower() == "userid")
										{
											strAnswer = userId.ToString();
										}
										else
										{
											if (oHiddenField.Value != string.Empty)
											{
												strAnswer = Utility.CleanInput(oHiddenField.Value, oFormControlInfo.AllowMarkup);
											}
										}
										
										AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
										break;
										
									case ControlType.FileUpload:
										FormFileDataInfo oFormFileDataInfo = default(FormFileDataInfo);
										HtmlInputFile oFileUpload = default(HtmlInputFile);
										oFileUpload = (HtmlInputFile) oHtmlControl;
										
										if (oFileUpload.Disabled == true)
										{
											break;
										}
										
										oFormFileDataInfo = null;
										
										strAnswer = Localization.GetString("NoUpload.Text", this._sharedResourceFile);
										
										//If Editing a record, we try to get the currently uploaded file information
										//just in case the upload field is not required, we don't want to overwrite the
										//current upload file information
										if (formDataId > 0)
										{
											foreach (FormFileDataInfo item in aryFileDataInfo)
											{
												if (item.ControlId == oFormControlInfo.ID)
												{
													oFormFileDataInfo = item;
													break;
												}
											}
										}
										
										if (oFormFileDataInfo == null)
										{
											oFormFileDataInfo = new FormFileDataInfo();
										}
										
										if ((oFileUpload.PostedFile != null) && (oFileUpload.PostedFile.FileName != string.Empty))
										{
											
											if (oFileUpload.PostedFile.ContentLength > (oFormControlInfo.MaxFileSize * 1000))
											{
												string strMsg = "";
												strMsg += Localization.GetString("FileSize.ErrorMessage", this._sharedResourceFile);
												strMsg = strMsg.Replace("[FILENAME]", oFileUpload.PostedFile.FileName);
												strMsg = strMsg.Replace("[MAXFILESIZE]", oFormControlInfo.MaxFileSize.ToString());
												throw (new IOException(strMsg));
											}
											
											//Get the File Name
											string[] aryPathParts = oFileUpload.PostedFile.FileName.Split('\\');
											if (aryPathParts.Length > 0)
											{
												strAnswer = aryPathParts[aryPathParts.Length - 1];
											}
											
											//If this is an Update we need to find the original file and update it.
											if (formDataId > 0)
											{
												if (oFormFileDataInfo != null)
												{
													
													//If this file is stored on the disk
													if (!oFormControlInfo.StoreInDB)
													{
														
														//If the original file name is not the same as the new file name delete the file
														if (oFormFileDataInfo.OrigFileName != strAnswer || oFormControlInfo.StoreInDB)
														{
															if (!string.IsNullOrEmpty(oFormFileDataInfo.FullFilePath))
															{
																if (File.Exists(HttpContext.Current.Server.MapPath(oFormFileDataInfo.FullFilePath)))
																{
																	File.Delete(HttpContext.Current.Server.MapPath(oFormFileDataInfo.FullFilePath));
																}
															}
														}
														
													}
													
												}
											}
											
											if (oFileUpload.PostedFile.FileName != string.Empty)
											{
												Guid oGuid = Guid.NewGuid();
												oFormFileDataInfo.ControlId = oFormControlInfo.ID;
												oFormFileDataInfo.CreatedByID = userId;
												oFormFileDataInfo.PortalId = portalId;
												oFormFileDataInfo.ModuleId = moduleId;
												oFormFileDataInfo.OrigFileName = strAnswer;
												oFormFileDataInfo.FileName = oGuid.ToString() + strAnswer;
												oFormFileDataInfo.ContentLegth = oFileUpload.PostedFile.ContentLength;
												oFormFileDataInfo.ContentType = oFileUpload.PostedFile.ContentType;
												
												if (string.IsNullOrEmpty(objFormSettings.GlobalUploadPath))
												{
													//oFormFileDataInfo.FilePath = Utility.GetAppPath()
													string homeDir = DotNetNuke.Entities.Portals.PortalController.GetCurrentPortalSettings().HomeDirectory;
													oFormFileDataInfo.FilePath = homeDir + "FormMaster/" + moduleId.ToString();
												}
												else
												{
													oFormFileDataInfo.FilePath = objFormSettings.GlobalUploadPath;
												}
												
												if (objFormCtl.FormInfo.SaveData)
												{
													oFormFileDataInfo.FormDataId = oFormDataInfo.FormDataID;
												}
												
												if (oFormControlInfo.StoreInDB)
												{
													oFormFileDataInfo.InDB = true;
													BinaryReader objBinaryReader = new BinaryReader(oFileUpload.PostedFile.InputStream);
													oFormFileDataInfo.FileData = objBinaryReader.ReadBytes(oFileUpload.PostedFile.ContentLength);
													//ReDim oFormFileDataInfo.FileData(oFileUpload.PostedFile.ContentLength - 1)
													//oFileUpload.PostedFile.InputStream.Read(oFormFileDataInfo.FileData, 0, oFileUpload.PostedFile.ContentLength - 1)
												}
												else
												{
													oFormFileDataInfo.InDB = false;
													if (!Directory.Exists(HttpContext.Current.Server.MapPath(oFormFileDataInfo.FilePath)))
													{
														Directory.CreateDirectory(HttpContext.Current.Server.MapPath(oFormFileDataInfo.FilePath));
													}
													
													string strAbsPath = HttpContext.Current.Server.MapPath(oFormFileDataInfo.FullFilePath);
													oFileUpload.PostedFile.SaveAs(strAbsPath);
													_alSavedFiles.Add(strAbsPath);
												}
												
												if (oFormFileDataInfo.FileDataId > 0)
												{
													oFileDataCtl.Update(oFormFileDataInfo);
												}
												else
												{
													oFormFileDataInfo.FileDataId = oFileDataCtl.Add(oFormFileDataInfo);
												}
												
												if (oFormControlInfo.AttachFile)
												{
													if (oFormControlInfo.StoreInDB)
													{
														XElement oAttachNode = new XElement("AttachFile");
														xFormPageElement.Add(oAttachNode);
														Utility.AddElement(xDoc, oAttachNode, "FileDataId", oFormFileDataInfo.FileDataId.ToString());
													}
													else
													{
														oGuid = Guid.NewGuid();
														string strAttachPath = HttpContext.Current.Server.MapPath(oFormFileDataInfo.AttachFilePath + oGuid.ToString() + strAnswer);
														oFileUpload.PostedFile.SaveAs(strAttachPath);
														
														XElement oAttachNode = new XElement("AttachFile");
														xFormPageElement.Add(oAttachNode);
														
														oAttachNode.Add(new XElement("AttachPath", strAttachPath));
														
														oAttachNode.Add(new XElement("FileName", new XCData(oFormFileDataInfo.OrigFileName)));
													}
												}
												
											}
										}
										
										if (oFormFileDataInfo.FileDataId > 0)
										{
											strAnswer = oFormFileDataInfo.GetDownloadUrl(portalId);
											AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer, true);
											
											//For Text formatted XSL output we need the plaing URL Without the
											//HTML Anchor Tags. We get this using Regular Expressions and put it
											//in a differently named Element "AnswerText" The Style Sheet looks for
											//"href" in the Answer and if found outputs the following-sibling which
											//will be the AnswerText Element below
											
											oAnswersElement.Add(new XElement("AnswerText", new XCData(Utility.GetTextModeUrl(strAnswer))));
										}
										else
										{
											AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
										}
										
										if (oFormControlInfo.ExcludeLink)
										{
											oAnswersElement.Add(new XAttribute("ExcludeLink", "1"));
										}
										break;
										
									case ControlType.HTMLEditor:
										if (oTextEditor != null)
										{
											strAnswer = pnlForm.Page.Server.HtmlDecode(Utility.CleanInput(oTextEditor.Text, oFormControlInfo.AllowMarkup));
										}
										
										AddAnswer(oFormControlInfo, xDoc, oAnswersElement, "Answer", strAnswer);
										break;
										
								}
								
								// Add the Field Token for the Auto Responder
								if (oFormControlInfo.ARToken != string.Empty)
								{
									oAnswersElement.Add(new XElement("ARToken", oFormControlInfo.ARToken));
								}
								
							} //If (oWebControl IsNot Nothing) OrElse (oHtmlControl IsNot Nothing) OrElse (oHiddenField IsNot Nothing)
							
							if (oFormControlInfo.Type != ControlType.FileUpload)
							{
								string paramAnswer = Utility.GetCsvFromNodeList(oAnswersElement.Descendants());
								switch (oFormControlInfo.SendValueBy)
								{
									case FormController.SendValueBy.Post:
									case FormController.SendValueBy.PostAndCookie:
									case FormController.SendValueBy.PostAndSession:
										strPostParams += this.SetSendValueBy(oFormControlInfo, oAnswersElement, paramAnswer);
										break;
									default:
										strQParams += this.SetSendValueBy(oFormControlInfo, oAnswersElement, paramAnswer);
										break;
								}
							}
							
							if (oFormControlInfo.ExcludeField)
							{
								if (oFieldElement != null)
								{
									oFieldElement.Remove();
								}
							}
							
						} //If oFormControlInfo.Type <> ControlType.Label AndAlso oFormControlInfo.Type <> ControlType.SubmitButton
					}
				}
			}
			
			xResultsDoc.Root.Add(new XElement("QParams", new XCData(strQParams)));
			
			xResultsDoc.Root.Add(new XElement("PostParams", new XCData(strPostParams)));
			
			if (objFormCtl.FormInfo.SaveData)
			{
				oFormDataInfo.FormData = xResultsDoc.ToString();
				
				if (objFormCtl.FormInfo.UseExtTable)
				{
					if (isUpdate)
					{
						UpdateExternalTable(objFormCtl, oFormDataInfo);
					}
					else
					{
						oFormDataInfo.ExtTableRowId = AddToExternalTable(objFormCtl, oFormDataInfo);
						if (Utility.SessionItemExists("ExtForeignKey") == false)
						{
							Utility.AddSessionItem("ExtForeignKey", oFormDataInfo.ExtTableRowId);
						}
					}
					
				}
				this.Update(oFormDataInfo);
			}
			return xResultsDoc;
		}
		
		public XElement AddAnswer(FormControlInfo controlInfo, XDocument xDoc, XElement parent, string elementName, string value, bool cdata = false)
		{
			XElement newElement = null;
			
			if (controlInfo.EncryptField)
			{
				value = Utility.DecryptString(value);
			}
			
			//newElement = Utility.AddElement(xDoc, parent, elementName, value, cdata)
			if (cdata)
			{
				newElement = new XElement(elementName, new XCData(value));
			}
			else
			{
				newElement = new XElement(elementName, value);
			}
			
			parent.Add(newElement);
			
			return newElement;
		}
		
		internal void GetSubmittedBy(XDocument objResultsXmlDoc, int portalId, int userId)
		{
			XElement xNode = default(XElement);
			XElement xFormResults = default(XElement);
			
			xFormResults = objResultsXmlDoc.Element("FormResults");
			if (xFormResults != null)
			{
				if (portalId >= 0)
				{
					string strUserInfo = "Unauthenticated User ";
					xNode = xFormResults.Element("Submitted_By");
					if (xNode == null)
					{
						xNode = Utility.AddElement(objResultsXmlDoc, xFormResults, "Submitted_By", "");
					}
					
					if (xNode != null)
					{
						if (userId > 0)
						{
							UserInfo objUserInfo = default(UserInfo);
							UserController objUserCtl = new UserController();
							objUserInfo = objUserCtl.GetUser(portalId, userId);
							
							if (objUserInfo != null)
							{
								strUserInfo = string.Format("{0} {1}", objUserInfo.FirstName, objUserInfo.LastName) + ",";
								
								strUserInfo += objUserInfo.Profile.Street + ",";
								
								strUserInfo += objUserInfo.Profile.City + ",";
								
								strUserInfo += objUserInfo.Profile.Region + ",";
								
								strUserInfo += objUserInfo.Profile.PostalCode + ",";
								
								strUserInfo += objUserInfo.Profile.Country + ",";
								
								strUserInfo += ",UID: " + objUserInfo.Username + ",";
								
							}
						}
						
						strUserInfo += "IP: " + HttpContext.Current.Request.ServerVariables["REMOTE_HOST"];
						
						xNode.Value = strUserInfo;
					}
				}
			}
		}
		
		// Sort the Controls Nodes by Row and Column so the results mimic the form layout on the page.
		public XDocument SortControls(XDocument xDoc, string modulePath)
		{
			XslCompiledTransform oTransDoc = default(XslCompiledTransform);
			XsltArgumentList oXsltArg = default(XsltArgumentList);
			StringWriter strStream = default(StringWriter);
			
			NameTable nt = new NameTable();
			
			XmlNamespaceManager nsmgr = new XmlNamespaceManager(nt);
			nsmgr.AddNamespace("", "");
			
			//Create the XmlParserContext.
			XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);
			
			oTransDoc = new XslCompiledTransform();
			oXsltArg = new XsltArgumentList();
			oTransDoc.Load(HttpContext.Current.Server.MapPath(modulePath + "assets/xslt/SortControls.xslt"));
			
			strStream = new StringWriter();
			
			XmlWriterSettings settings = new XmlWriterSettings();
			settings.OmitXmlDeclaration = false;
			settings.ConformanceLevel = ConformanceLevel.Auto;
			settings.CloseOutput = false;
			
			oTransDoc.Transform(new XmlTextReader(xDoc.ToString(), XmlNodeType.Document, context), oXsltArg, XmlWriter.Create(strStream, settings), null);
			
			xDoc = XDocument.Parse(strStream.ToString());
			
			return xDoc;
		}
		
		private string SetSendValueBy(FormControlInfo oFormControlInfo, XElement ansNodes, string value)
		{
			string strParam = string.Empty;
			string tempParams = string.Empty;
			DateTime dtCookieExpires = DateTime.MinValue;
			
			if (oFormControlInfo.CookieExpires > 0)
			{
				dtCookieExpires = DateTime.Now.AddDays(oFormControlInfo.CookieExpires);
			}
			
			switch (oFormControlInfo.SendValueBy)
			{
				
			case FormController.SendValueBy.Cookie:
				Utility.SetCookie(oFormControlInfo.SendValueByName, value, dtCookieExpires);
				break;
				
			case FormController.SendValueBy.Session:
				HttpContext.Current.Session.Add(oFormControlInfo.SendValueByName, value);
				break;
				
			case FormController.SendValueBy.Url:
				if (oFormControlInfo.Type == ControlType.CheckBoxList || oFormControlInfo.Type == ControlType.ListBox)
				{
					tempParams = GetMultiValuedParams(oFormControlInfo, ansNodes.Elements());
					if (!string.IsNullOrEmpty(tempParams))
					{
						strParam = tempParams;
					}
					else
					{
						strParam = "&" + oFormControlInfo.SendValueByName + "=" + HttpUtility.UrlEncode(value);
					}
				}
				else
				{
					strParam = "&" + oFormControlInfo.SendValueByName + "=" + HttpUtility.UrlEncode(value);
				}
				break;
				
			case FormController.SendValueBy.Post:
				value = HttpUtility.UrlEncode(value);
				if (oFormControlInfo.Type == ControlType.CheckBoxList || oFormControlInfo.Type == ControlType.ListBox)
				{
					tempParams = GetMultiValuedParams(oFormControlInfo, ansNodes.Elements());
					if (!string.IsNullOrEmpty(tempParams))
					{
						strParam = tempParams;
					}
					else
					{
						strParam = "&" + HttpUtility.UrlEncode(oFormControlInfo.SendValueByName) + "=" + value;
					}
				}
				else
				{
					strParam = "&" + HttpUtility.UrlEncode(oFormControlInfo.SendValueByName) + "=" + value;
				}
				break;
				
				
			case FormController.SendValueBy.PostAndSession:
				HttpContext.Current.Session.Add(oFormControlInfo.SendValueByName, value);
				value = HttpUtility.UrlEncode(value);
				if (oFormControlInfo.Type == ControlType.CheckBoxList || oFormControlInfo.Type == ControlType.ListBox)
				{
					tempParams = GetMultiValuedParams(oFormControlInfo, ansNodes.Elements());
					if (!string.IsNullOrEmpty(tempParams))
					{
						strParam = tempParams;
					}
					else
					{
						strParam = "&" + HttpUtility.UrlEncode(oFormControlInfo.SendValueByName) + "=" + value;
					}
				}
				else
				{
					strParam = "&" + HttpUtility.UrlEncode(oFormControlInfo.SendValueByName) + "=" + value;
				}
				break;
				
				
			case FormController.SendValueBy.PostAndCookie:
				Utility.SetCookie(oFormControlInfo.SendValueByName, value, dtCookieExpires);
				value = HttpUtility.UrlEncode(value);
				if (oFormControlInfo.Type == ControlType.CheckBoxList || oFormControlInfo.Type == ControlType.ListBox)
				{
					tempParams = GetMultiValuedParams(oFormControlInfo, ansNodes.Elements());
					if (!string.IsNullOrEmpty(tempParams))
					{
						strParam = tempParams;
					}
					else
					{
						strParam = "&" + HttpUtility.UrlEncode(oFormControlInfo.SendValueByName) + "=" + value;
					}
				}
				else
				{
					strParam = "&" + HttpUtility.UrlEncode(oFormControlInfo.SendValueByName) + "=" + value;
				}
				break;
				
		}
		
		return strParam;
		
	}
	
	private string GetMultiValuedParams(FormControlInfo oFormControlInfo, IEnumerable<XElement> ansNodes)
	{
		string tempParams = string.Empty;
		string tempValue = string.Empty;
		XAttribute pNameNode = default(XAttribute);
		
		foreach (XElement node in ansNodes)
		{
			pNameNode = node.Attribute("ParamName");
			if (pNameNode != null)
			{
				if (oFormControlInfo.SendValueBy == FormController.SendValueBy.Url)
				{
					tempValue = HttpUtility.UrlEncode(node.Value);
				}
				else
				{
					tempValue = node.Value;
				}
				tempParams += "&" + pNameNode.Value + "=" + tempValue;
			}
		}
		
		return tempParams;
		
	}
	
#endregion
	
}

}

